#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
视频处理功能模块
负责实现视频处理相关的核心功能
"""

import os
import tempfile
from PySide6.QtWidgets import QFileDialog, QMessageBox
from PySide6.QtGui import QPixmap, QImage
from src.config import Config
from src.video.segment_manager import SegmentType


class VideoFunctions:
    """视频处理功能类"""
    
    def __init__(self):
        """初始化视频处理功能"""
        pass
    
    def import_video(self, window):
        """
        导入视频文件
        
        通过文件对话框选择一个或多个视频文件并加载，提取视频信息，
        初始化播放器状态，并更新UI元素以反映新加载的视频。
        支持多种常见视频格式，包括MP4、AVI、MOV、MKV等。
        
        Args:
            window (VideoStitcherMainWindow): 主窗口实例
            
        Note:
            - 使用QFileDialog让用户选择视频文件，支持多选
            - 支持的视频格式包括：mp4, avi, mov, mkv, flv, wmv, webm
            - 如果选择了多个文件，默认加载第一个文件
            - 成功导入后会自动显示视频的第一帧
            - 导入成功后会启用播放控制按钮
            - 如果导入过程中出现错误，会弹出错误提示框
        """
        file_paths, _ = QFileDialog.getOpenFileNames(
            window,
            Config.FILE_DIALOG_TITLE,
            "",
            Config.FILE_DIALOG_FILTER
        )
        
        if file_paths:
            # 默认加载第一个选中的文件
            file_path = file_paths[0]
            
            try:
                # 加载视频到video_processor
                window.video_processor.load_video(file_path)
                
                # 加载视频到FFmpeg播放器
                if window.ffmpeg_player.load_video(file_path):
                    # 获取视频信息
                    duration = window.ffmpeg_player.get_duration()
                    
                    # 更新UI
                    window.progress_slider.setMaximum(int(duration * 1000))  # 转换为毫秒
                    window.time_label.setText(f"00:00:00 / {window.format_time(duration)}")
                    window.setWindowTitle(f"{Config.WINDOW_TITLE} - {file_path.split('/')[-1]}")
                    
                    # 显示第一帧
                    window.show_frame_at_time(0)
                    
                    # 启用控件
                    window.enable_controls(True)
                else:
                    QMessageBox.warning(window, "错误", "无法加载视频文件到FFmpeg播放器")
                    return
                
                # 显示成功消息，包含选中的文件数量
                if len(file_paths) > 1:
                    QMessageBox.information(window, Config.SUCCESS_TITLE, 
                                          f"成功导入 {len(file_paths)} 个视频文件，当前显示: {os.path.basename(file_path)}")
                else:
                    QMessageBox.information(window, Config.SUCCESS_TITLE, Config.SUCCESS_IMPORT_MESSAGE)
                    
                # 存储所有选中的文件路径，以备后用
                window.selected_video_files = file_paths
                
                # 更新视频列表显示
                window.video_list_area.update_video_list(file_paths, 0)
                
            except Exception as e:
                QMessageBox.critical(window, Config.ERROR_TITLE, f"导入视频失败: {str(e)}")
    
    def toggle_play_pause(self, window):
        """
        切换播放/暂停状态
        
        使用FFmpeg播放器控制视频的播放和暂停状态切换。
        
        Args:
            window (VideoStitcherMainWindow): 主窗口实例
            
        Note:
            - 使用FFmpeg播放器进行音视频同步播放
            - 按钮文本会根据播放状态动态更新
            - is_playing属性用于跟踪当前播放状态
        """
        if window.is_playing:
            window.ffmpeg_player.pause()
            window.play_pause_button.setText(Config.PLAY_BUTTON_TEXT)
            window.is_playing = False
        else:
            window.ffmpeg_player.play()
            window.play_pause_button.setText(Config.PAUSE_BUTTON_TEXT)
            window.is_playing = True
    
    def switch_video(self, window):
        """
        切换到下一个视频文件
        
        在已导入的多个视频文件之间切换，循环显示。
        
        Args:
            window (VideoStitcherMainWindow): 主窗口实例
            
        Note:
            - 如果只有一个视频或没有视频，则不执行任何操作
            - 循环切换到下一个视频文件
            - 切换后会重置播放状态并显示第一帧
            - 更新按钮文本显示当前视频索引
        """
        if not window.selected_video_files or len(window.selected_video_files) <= 1:
            return
            
        # 找到当前视频在列表中的索引
        current_file = window.windowTitle().replace(f"{Config.WINDOW_TITLE} - ", "")
        try:
            current_index = next(i for i, path in enumerate(window.selected_video_files) 
                               if path.split('/')[-1] == current_file)
            # 切换到下一个视频（循环）
            next_index = (current_index + 1) % len(window.selected_video_files)
        except StopIteration:
            # 如果找不到当前视频，从第一个开始
            next_index = 0
            
        self.switch_to_video_at_index(window, next_index)
    
    def switch_to_video_at_index(self, window, index):
        """
        切换到指定索引的视频文件
        
        Args:
            window (VideoStitcherMainWindow): 主窗口实例
            index (int): 要切换到的视频索引
            
        Note:
            - 切换到指定索引的视频文件
            - 切换后会重置播放状态并显示第一帧
            - 更新按钮文本显示当前视频索引
        """
        if not window.selected_video_files or index < 0 or index >= len(window.selected_video_files):
            return
            
        # 加载指定索引的视频
        file_path = window.selected_video_files[index]
        try:
            # 停止当前播放
            if window.is_playing:
                window.ffmpeg_player.stop()
            
            # 加载视频到video_processor
            window.video_processor.load_video(file_path)
            
            # 加载视频到FFmpeg播放器
            if window.ffmpeg_player.load_video(file_path):
                # 获取视频信息
                duration = window.ffmpeg_player.get_duration()
                
                # 更新UI
                window.progress_slider.setMaximum(int(duration * 1000))  # 转换为毫秒
                window.time_label.setText(f"00:00:00 / {window.format_time(duration)}")
                window.setWindowTitle(f"{Config.WINDOW_TITLE} - {file_path.split('/')[-1]}")
                
                # 显示第一帧
                window.show_frame_at_time(0)
                
                # 更新按钮文本
                window.switch_video_button.setText(f"切换视频 ({index + 1}/{len(window.selected_video_files)})")
                
                # 更新视频列表显示
                window.video_list_area.update_video_list(window.selected_video_files, index)
                
                # 重置播放状态
                window.is_playing = False
                window.play_pause_button.setText(Config.PLAY_BUTTON_TEXT)
            else:
                QMessageBox.warning(window, "错误", "无法加载视频文件到FFmpeg播放器")
                return
            
        except Exception as e:
            QMessageBox.critical(window, Config.ERROR_TITLE, f"切换视频失败: {str(e)}")

    def show_frame_at_time(self, window, time_in_seconds):
        """
        在指定时间显示视频帧
        
        从视频处理器获取指定时间的视频帧，并将其显示在预览区域。
        如果获取帧成功，则更新当前帧的像素图并显示在标签上；
        如果获取失败，则显示错误信息。
        
        Args:
            window (VideoStitcherMainWindow): 主窗口实例
            time_in_seconds (float): 要显示的帧的时间位置（秒）
            
        Note:
            - 使用video_processor获取指定时间的帧
            - 帧以QPixmap形式显示在video_label上
            - 函数会更新current_time属性
        """
        try:
            # 获取指定时间的帧
            frame = window.video_processor.get_frame_at_time(time_in_seconds)
            
            if frame is not None:
                # 转换颜色空间（BGR到RGB）
                rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                
                # 创建QImage
                h, w, ch = rgb_frame.shape
                bytes_per_line = ch * w
                q_img = QImage(rgb_frame.data, w, h, bytes_per_line, QImage.Format_RGB888)
                
                # 创建QPixmap并显示
                window.current_frame_pixmap = QPixmap.fromImage(q_img)
                window.video_label.setPixmap(window.current_frame_pixmap.scaled(
                    window.video_label.width(),
                    window.video_label.height(),
                    Qt.KeepAspectRatio,
                    Qt.SmoothTransformation
                ))
                
                # 更新当前时间
                window.current_time = time_in_seconds
            else:
                window.video_label.setText("无法获取视频帧")
        except Exception as e:
            window.video_label.setText(f"显示帧时出错: {str(e)}")